package com.egghiro.j2se.game.scardbattle.controller.battle;

import java.util.Random;

import com.egghiro.j2se.game.scardbattle.model.character.monster.KingSlime;
import com.egghiro.j2se.game.scardbattle.model.character.monster.Magician;
import com.egghiro.j2se.game.scardbattle.model.character.monster.Monster;
import com.egghiro.j2se.game.scardbattle.model.character.monster.Slime;
import com.egghiro.j2se.game.scardbattle.model.character.player.PlayerCharacter;
import com.egghiro.j2se.game.scardbattle.model.gamedata.PlayerData;
import com.egghiro.j2se.game.scardbattle.param.Message;
import com.egghiro.j2se.game.scardbattle.view.console.CardBattleConsoleView;

import consolegame.framework.ConsoleGame;

public class Battle extends ConsoleGame {

    // 戦闘時間計測開始
    private long startTime;
    // 戦闘が継続中であることを示すフラグ
    private boolean commandFlag; // TODO　気に入らないやり方。あとで変える

    private Monster monster; // TODO
    private int turnCount;

    public Monster encount() {
        // TODO 各モンスターを下記の確率で出現させる(＝出現させたい各モンスタークラスのインスタンスを戻り値として返す)
        // TODO 30%の確率で魔法使い(Magician)が出現
        // TODO 20%の確率でキングスライム(KingSlime)が出現
        // TODO 50%の確率でスライム(Slime)が出現
        Monster monster = null;
        // TODO
        int randomInt = (new Random()).nextInt(10) + 1;
        if(randomInt <= 3){
            monster = new Magician();
        } else if(randomInt <= 5) {
            monster = new KingSlime();
        } else {
            monster = new Slime();
        }

        System.out.println("");
        System.out.println(monster.getName() + Message.MSG_BATTLE_START);

        return monster;
    }

    public void states(PlayerCharacter playerCharacyer, Monster monster) {
        System.out.println("┌------------------------");
        System.out.println("｜" + playerCharacyer.getName() + " HP:" + playerCharacyer.getHp() + " MP:" + playerCharacyer.getMp());
        System.out.println("｜" + monster.getName() + " HP:" + monster.getHp() + " MP:" + monster.getMp());
        System.out.println("└------------------------");
    }

    // TODO モンスターの行動ロジックは各モンスタークラスに
    /**
     * モンスターの行動を起こす。戦闘継続時はtrue、戦闘終了時はfalseを返す。
     * 
     * @param soldier
     *            戦士のインスタンス
     * @param monster
     *            モンスターのインスタンス
     * @return 戦闘継続時はtrue、戦闘終了時はfalse
     */
    public boolean doMonsterAction(PlayerCharacter playerCharacter, Monster monster) {
        Random rand = new Random();
        // 1～10までの乱数を生成
        int actNum = rand.nextInt(10) + 1;

        int monsterAttackPoint = 0;
        
        monster.act();

//        if (monster instanceof Magician) {
//            if (actNum >= 1 && actNum <= 5) {
//                // 50%の確率で魔法攻撃
//                System.out.print(monster.getName() + Message.MSG_MAGIC_START);
//                Magician magician = (Magician) monster;
//                monsterAttackPoint = magician.magic(playerCharacter);
//                if (monsterAttackPoint > 0) {
//                    System.out.println(monsterAttackPoint + Message.MSG_MONSTER_ATTACK_END);
//                }
//                return true;
//            }
//        }
//
//        if (monster instanceof KingSlime) {
//            if (actNum >= 1 && actNum <= 3) {
//                // 30%の確率で魔法攻撃
//                System.out.print(monster.getName() + Message.MSG_MAGIC_START);
//                KingSlime magician = (KingSlime) monster;
//                monsterAttackPoint = magician.magic(playerCharacter);
//                if (monsterAttackPoint > 0) {
//                    System.out.println(monsterAttackPoint + Message.MSG_MONSTER_ATTACK_END);
//                }
//                return true;
//            } else if (actNum >= 4 && actNum <= 7) {
//                // 40%の確率で逃げる
//                System.out.println(monster.getName() + Message.MSG_BATTLE_ESCAPE);
//                return false;
//            }
//        }
//
//        // 通常攻撃
//        monsterAttackPoint = monster.attack(playerCharacter);
//        System.out.print(monster.getName() + Message.MSG_ATTACK_START);
//        System.out.println(monsterAttackPoint + Message.MSG_MONSTER_ATTACK_END);
        return true;
    }

    public boolean isBattleOver() {
        // TODO
        return (CardBattleConsoleView.getInstance().getSoldier().getHp() <= 0 || this.monster.getHp() <= 0);
    }

    @Override
    protected boolean loadGame() {

        // 戦闘時間計測開始
        startTime = System.currentTimeMillis();
        // 戦闘が継続中であることを示すフラグ
        commandFlag = true;

        // 以下 TODO
        // モンスター出現
        this.monster = this.encount();

        // 戦闘ターン数
        this.turnCount = 0;

        return true;
    }

    @Override
    protected void act() {
        System.out.println("");
        try {
            // 0.5秒待機
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        // ターン数をカウントアップ
        turnCount++;
        
        PlayerCharacter playerCharacter = CardBattleConsoleView.getInstance().getSoldier();

        // 現在の戦士とモンスターのHP/MPを表示
        this.states(playerCharacter, monster);

        // 戦士の行動（コマンド）を受け付ける
        String action = command(turnCount + "ターン目:" + Message.MSG_BATTLE_ATTACK_COMMAND);

        // 戦士がモンスターに与えるダメージ
        int soldierAttackPoint = 0;

        if (action.equals("attack") || action.equals("a")) {
            // 戦士の通常攻撃
            System.out.print(playerCharacter.getName() + Message.MSG_ATTACK_START);
            soldierAttackPoint = playerCharacter.attack(monster);
            System.out.println(soldierAttackPoint + Message.MSG_SOLDIER_ATTACK_END);
        } else if (action.equals("magic") || action.equals("m")) {
            // 戦士の魔法攻撃
            System.out.print(playerCharacter.getName() + Message.MSG_MAGIC_START);
            playerCharacter.setMp(playerCharacter.getMp() - 20);

            if (playerCharacter.getMp() < 0) {
                playerCharacter.setMp(0);
                System.out.println(Message.MSG_MAGIC_START_NG);
            } else {
                soldierAttackPoint = playerCharacter.magic(monster);
                System.out.println(soldierAttackPoint + Message.MSG_SOLDIER_ATTACK_END);
            }
        } else if (action.equals("kaifuku") || action.equals("k")) {
            // 戦士のHP回復
            System.out.print(playerCharacter.getName() + Message.MSG_MAGIC_START);
            playerCharacter.setMp(playerCharacter.getMp() - 10);

            if (playerCharacter.getMp() < 0) {
                playerCharacter.setMp(0);
                System.out.println(Message.MSG_MAGIC_START_NG);
            } else {
                playerCharacter.setHp(playerCharacter.getHp() + 100);
                System.out.println(Message.MSG_HP100KAIFUKU);
            }
        } else if (action.equals("quit") || action.equals("q")) {
            commandFlag = false;
//            break;
        } else {
            // TODO　規定外のコマンドの場合、今は終了するだけ⇒もう一回入力させる
            commandFlag = false;
        }

        // モンスターの行動
        if(monster.getHp() > 0){ // TODO
            this.doMonsterAction(playerCharacter, monster);
        }
        
    }
//
//    @Override
//    protected void showInputMessage() {
//        // TODO
//        // do nothing
//    }
//
//    @Override
//    protected void showErrorMessage() {
//        // TODO
//        // do nothing
//    }

    @Override
    protected boolean isGameClear() {
        // TODO
        return monster.getHp() <= 0;
    }

    @Override
    protected boolean isGameOver() {
        // TODO
        return CardBattleConsoleView.getInstance().getSoldier().getHp() <= 0;
    }
    
    @Override
    protected void doGameClear(){
        System.out.println(monster.getName() + Message.MSG_BATTLE_WIN);
        
        PlayerCharacter playerCharacter = CardBattleConsoleView.getInstance().getSoldier();
        PlayerData playerData = CardBattleConsoleView.getInstance().getPlayerData();

        // モンスターのHPが0以下の場合は経験値とアイテムを取得
        if(monster.getHp() <= 0){
            // TODO
            int exp = monster.getExp();
            playerCharacter.setExp(playerCharacter.getExp() + exp);
            int gold = monster.getGold();
            playerData.setGold(playerData.getGold() + gold);
//            // 倒したモンスター数をカウントアップ
//            monsterCount++;
            System.out.println("経験値" + exp + "と" + gold + "ゴールド" + Message.MSG_DROP);
            System.out.println("経験値合計:" + playerCharacter.getExp() + "　ゴールド合計:" + playerData.getGold());
            
        }

    }
    
    @Override
    protected void doGameOver(){
        // 戦士のHPが0以下の場合は敗北
        System.out.println(CardBattleConsoleView.getInstance().getSoldier().getName() + Message.MSG_BATTLE_LOST);
    }

    @Override
    protected void doGameEnd() {
        // TODO
//        // 戦闘時間計測終了
//        int endTime = (int) ((System.currentTimeMillis() - startTime) / 1000);

        
        System.out.println();
        
        try {
            // 1秒待機
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
